package cn.lijiajia3515.cairo.auth.modules.department;

import cn.lijiajia3515.cairo.core.page.Page;
import cn.lijiajia3515.cairo.security.oauth2.jwt.CairoJwtPrincipal;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.util.List;
import java.util.Optional;

/**
 * Department Api
 */
@RestController
@RequestMapping("/api/department")
public class DepartmentApi {

	private final DepartmentService departmentService;

	public DepartmentApi(DepartmentService departmentService) {
		this.departmentService = departmentService;
	}

	@PostMapping("/find")
	@PreAuthorize("hasAnyAuthority('scp_find:department')")
	public List<Department> find(@AuthenticationPrincipal CairoJwtPrincipal principal,
								 @RequestBody FindDepartmentParam param) {
		return departmentService.find(principal.getAppId(), param);
	}

	@PostMapping("/find/page")
	@PreAuthorize("hasAnyAuthority('scp_find:department')")
	public Page<Department> findPage(@AuthenticationPrincipal CairoJwtPrincipal principal,
									 @RequestBody FindDepartmentParam param) {
		return departmentService.findPage(principal.getAppId(), param);
	}

	@PostMapping("/find/ancestor")
	@PreAuthorize("hasAnyAuthority('scp_find:department')")
	public List<PathDepartment> findAncestors(@AuthenticationPrincipal CairoJwtPrincipal principal,
											  @RequestBody FindDepartmentParam param) {
		return departmentService.findAncestorDepartment(principal.getAppId(), param);
	}

	@PostMapping("/find/tree")
	@PreAuthorize("hasAnyAuthority('scp_find:department')")
	public List<DepartmentTreeNode> treeFind(@AuthenticationPrincipal CairoJwtPrincipal principal, @RequestBody FindTreeDepartmentParam param) {

		return departmentService.findTree(principal.getAppId(), param);
	}

	@GetMapping("/find/id/{id}")
	@PreAuthorize("hasAnyAuthority('scp_find:department')")
	public Optional<PathDepartment> find(@AuthenticationPrincipal CairoJwtPrincipal principal,
										 @PathVariable String id) {
		return departmentService.findId(principal.getAppId(), id);
	}

	@PostMapping("/save")
	@PreAuthorize("hasAnyAuthority('scp_find:department')")
	public Department save(@AuthenticationPrincipal CairoJwtPrincipal principal,
						   @RequestBody @Valid @Validated SaveDepartmentParam request) {
		return departmentService.save(principal.getAppId(), request);
	}

	@PutMapping("/modify")
	@PreAuthorize("hasAnyAuthority('scp_modify_department')")
	public Department put(@AuthenticationPrincipal CairoJwtPrincipal principal, @RequestBody ModifyDepartmentParam param) {
		return departmentService.modify(principal.getAppId(), param).orElseThrow();
	}

	@DeleteMapping("/delete")
	@PreAuthorize("hasAnyAuthority('scp_delete:department')")
	public List<Department> delete(@AuthenticationPrincipal CairoJwtPrincipal principal, @RequestBody DeleteDepartmentParam param) {
		return departmentService.delete(principal.getAppId(), param);
	}

}
